package com.getpebble.android.framework.install;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;

public class Stm32Crc {
    private byte[] mBuffer;
    private int mCrc;
    private boolean mIsFinalized;
    private boolean mIsLittleEndian;

    public Stm32Crc() {
        this(false);
    }

    public Stm32Crc(boolean isLittleEndian) {
        this.mIsLittleEndian = false;
        this.mCrc = -1;
        this.mBuffer = null;
        this.mIsFinalized = false;
        this.mIsLittleEndian = isLittleEndian;
    }

    public Stm32Crc addBytes(byte[] data, int dataLength) {
        if (this.mIsFinalized) {
            throw new IllegalStateException("Cannot addBytes once CRC is finalized.");
        }
        addBytesToBuffer(data, dataLength);
        processBuffer();
        return this;
    }

    public int finalizeCrc() {
        if (this.mIsFinalized) {
            return this.mCrc;
        }
        if (!(this.mBuffer == null || this.mBuffer.length >= 4 || this.mBuffer.length == 0)) {
            ByteBuffer bb = ByteBuffer.allocate(4);
            if (this.mIsLittleEndian) {
                bb.order(ByteOrder.LITTLE_ENDIAN);
            } else {
                bb.order(ByteOrder.BIG_ENDIAN);
            }
            for (int i = this.mBuffer.length; i < 4; i++) {
                bb.put((byte) 0);
            }
            bb.put(this.mBuffer, 0, this.mBuffer.length);
            stm32CrcProcessWord(bb.getInt(0));
        }
        this.mIsFinalized = true;
        return this.mCrc;
    }

    private void addBytesToBuffer(byte[] data, int dataLength) {
        if (this.mBuffer == null) {
            this.mBuffer = Arrays.copyOf(data, dataLength);
            return;
        }
        byte[] newBuffer = new byte[(this.mBuffer.length + dataLength)];
        System.arraycopy(this.mBuffer, 0, newBuffer, 0, this.mBuffer.length);
        System.arraycopy(data, 0, newBuffer, this.mBuffer.length, dataLength);
        this.mBuffer = newBuffer;
    }

    private void processBuffer() {
        ByteBuffer bb = ByteBuffer.allocate(4);
        bb.order(ByteOrder.LITTLE_ENDIAN);
        for (int word_counter = 0; word_counter < this.mBuffer.length / 4; word_counter++) {
            bb.put(this.mBuffer, word_counter * 4, 4);
            stm32CrcProcessWord(bb.getInt(0));
            bb.clear();
        }
        this.mBuffer = Arrays.copyOfRange(this.mBuffer, this.mBuffer.length - (this.mBuffer.length % 4), this.mBuffer.length);
    }

    private int stm32CrcProcessWord(int data) {
        this.mCrc ^= data;
        for (int i = 0; i < 32; i++) {
            if ((this.mCrc & Integer.MIN_VALUE) != 0) {
                this.mCrc = (this.mCrc << 1) ^ 79764919;
            } else {
                this.mCrc <<= 1;
            }
        }
        return this.mCrc;
    }
}
